# lib/feep/constants.rb

module Feep
  # constants
  SNDPLAYER_WIN = 'sounder.exe'
  SNDPLAYER_UNIX = 'afplay'
  SAMPLE_RATE = 44100
  TWO_PI = 2 * Math::PI
  RANDOM_GENERATOR = Random.new
  WAVE_TYPES = %w[sine square saw triangle noise]

  # tables of musical data
  SCALES = Hash[
    :chromatic          => '1,1,1,1,1,1,1,1,1,1,1,1,1',
    :whole_tone         => '2,2,2,2,2,2,2',
    :major              => '2,2,2,1,2,2,2,1',
    :minor_harm         => '2,1,2,2,1,3,3',
    :minor_melodic      => '2,1,2,2,2,2,3',
    :major_pentatonic   => '2,2,3,2,3,2',
    :minor_pentatonic   => '3,2,2,3,2,3',
    :blues              => '3,2,1,1,3,2,3',
    :phyrgian           => '1,2,2,2,1,2,2,2',
    :dorian             => '2,1,2,2,2,1,2,2'
  ]
  NOTES = Array[
  'C0','C#0','D0','D#0','E0','F0','F#0','G0','G#0','A0','A#0','B0',
  'C1','C#1','D1','D#1','E1','F1','F#1','G1','G#1','A1','A#1','B1',
  'C2','C#2','D2','D#2','E2','F2','F#2','G2','G#2','A2','A#2','B2',
  'C3','C#3','D3','D#3','E3','F3','F#3','G3','G#3','A3','A#3','B3',
  'C4','C#4','D4','D#4','E4','F4','F#4','G4','G#4','A4','A#4','B4',
  'C5','C#5','D5','D#5','E5','F5','F#5','G5','G#5','A5','A#5','B5',
  'C6','C#6','D6','D#6','E6','F6','F#6','G6','G#6','A6','A#6','B6',
  'C7','C#7','D7','D#7','E7','F7','F#7','G7','G#7','A7','A#7','B7',
  'C8','C#8','D8','D#8','E8','F8','F#8','G8','G#8','A8','A#8','B8',
  'C9','C#9','D9','D#9','E9','F9','F#9','G9','G#9','A9','A#9','B9'
  ]
  NOTES_ALT = Array[
  'C0','Db0','D0','Eb0','E0','F0','Gb0','G0','Ab0','A0','Bb0','B0',
  'C1','Db1','D1','Eb1','E1','F1','Gb1','G1','Ab1','A1','Bb1','B1',
  'C2','Db2','D2','Eb2','E2','F2','Gb2','G2','Ab2','A2','Bb2','B2',
  'C3','Db3','D3','Eb3','E3','F3','Gb3','G3','Ab3','A3','Bb3','B3',
  'C4','Db4','D4','Eb4','E4','F4','Gb4','G4','Ab4','A4','Bb4','B4',
  'C5','Db5','D5','Eb5','E5','F5','Gb5','G5','Ab5','A5','Bb5','B5',
  'C6','Db6','D6','Eb6','E6','F6','Gb6','G6','Ab6','A6','Bb6','B6',
  'C7','Db7','D7','Eb7','E7','F7','Gb7','G7','Ab7','A7','Bb7','B7',
  'C8','Db8','D8','Eb8','E8','F8','Gb8','G8','Ab8','A8','Bb8','B8',
  'C9','Db9','D9','Eb9','E9','F9','Gb9','G9','Ab9','A9','Bb9','B9'
  ]

  FREQS = Array[
  16.351,17.324,18.354,19.445,20.601,21.827,23.124,24.499,25.956,27.500,29.135,30.868,
  32.703,34.648,36.708,38.891,41.203,43.654,46.249,48.999,51.913,55.000,58.270,61.375,
  65.406,69.296,73.416,77.782,82.407,87.307,92.499,97.999,103.826,110.000,116.541,
  123.471,130.813,138.591,146.832,155.564,164.814,174.614,184.997,195.998,207.652,220.000,233.082,246.942,
  261.626,277.183,293.665,311.127,329.628,349.228,369.994,391.995,415.305,440.000,466.164,493.883,
  523.251,554.365,587.330,622.254,659.255,698.457,739.989,783.991,830.609,880.000,932.328,987.767,
  1046.502,1108.731,1174.659,1244.508,1318.510,1396.913,1479.978,1567.982,1661.219,1760.000,1864.655,1975.533,
  2093.005,2217.461,2349.318,2489.016,2637.021,2793.826,2959.956,3135.964,3322.438,3520.000,3729.310,3951.066,
  4186.009,4434.922,4698.636,4978.032,5274.042,5587.652,5919.910,6271.928,6644.876,7040.000,7458.620,7902.132,
  8372.018,8869.844,9397.272,9956.064,10548.084,11175.304,11839.820,12543.856,13289.752,14080.000,14917.240,15804.264
  ]

  MIDIS = Array[
   12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,
   24,  25,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,
   36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,
   48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,
   60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  71,
   72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,
   84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,
   96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107,
  108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
  120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131
  ]

  NOTE_FREQ = Hash[
  'C0' =>     16.351,
  'C#0' =>    17.324,
  'Db0' =>    17.324,
  'D0' =>     18.354,
  'D#0' =>    19.445,
  'Eb0' =>    19.445,
  'E0' =>     20.601,
  'F0' =>     21.827,
  'F#0' =>    23.124,
  'Gb0' =>    23.124,
  'G0' =>     24.499,
  'G#0' =>    25.956,
  'Ab0' =>    25.956,
  'A0' =>     27.500,
  'A#0' =>    29.135,
  'Bb0' =>    29.135,
  'B0' =>     30.868,
  'C1' =>     32.703,
  'C#1' =>    34.648,
  'Db1' =>    34.648,
  'D1' =>     36.708,
  'D#1' =>    38.891,
  'Eb1' =>    38.891,
  'E1' =>     41.203,
  'F1' =>     43.654,
  'F#1' =>    46.249,
  'Gb1' =>    46.249,
  'G1' =>     48.999,
  'G#1' =>    51.913,
  'Ab1' =>    51.913,
  'A1' =>     55.000,
  'A#1' =>    58.270,
  'Bb1' =>    58.270,
  'B1' =>     61.375,
  'C2' =>     65.406,
  'C#2' =>    69.296,
  'Db2' =>    69.296,
  'D2' =>     73.416,
  'D#2' =>    77.782,
  'Eb2' =>    77.782,
  'E2' =>     82.407,
  'F2' =>     87.307,
  'F#2' =>    92.499,
  'Gb2' =>    92.499,
  'G2' =>     97.999,
  'G#2' =>    97.999,
  'Ab2' =>   103.826,
  'A2' =>    110.000,
  'A#2' =>   116.541,
  'Bb2' =>   116.541,
  'B2' =>    123.471,
  'C3' =>    130.813,
  'C#3' =>   138.591,
  'Db3' =>   138.591,
  'D3' =>    146.832,
  'D#3' =>   155.564,
  'Eb3' =>   155.564,
  'E3' =>    164.814,
  'F3' =>    174.614,
  'F#3' =>   184.997,
  'Gb3' =>   184.997,
  'G3' =>    195.998,
  'G#3' =>   207.652,
  'Ab3' =>   207.652,
  'A3' =>    220.000,
  'A#3' =>   233.082,
  'Bb3' =>   233.082,
  'B3' =>    246.942,
  'C4' =>    261.626,
  'C#4' =>   277.183,
  'Db4' =>   277.183,
  'D4' =>    293.665,
  'D#4' =>   311.127,
  'Eb4' =>   311.127,
  'E4' =>    329.628,
  'F4' =>    349.228,
  'F#4' =>   369.994,
  'Gb4' =>   369.994,
  'G4' =>    391.995,
  'G#4' =>   415.305,
  'Ab4' =>   415.305,
  'A4' =>    440.000,
  'A#4' =>   466.164,
  'Bb4' =>   466.164,
  'B4' =>    493.883,
  'C5' =>    523.251,
  'C#5' =>   554.365,
  'Db5' =>   554.365,
  'D5' =>    587.330,
  'D#5' =>   622.254,
  'Eb5' =>   622.254,
  'E5' =>    659.255,
  'F5' =>    698.457,
  'F#5' =>   739.989,
  'Gb5' =>   739.989,
  'G5' =>    783.991,
  'G#5' =>   830.609,
  'Ab5' =>   830.609,
  'A5' =>    880.000,
  'A#5' =>   932.328,
  'Bb5' =>   932.328,
  'B5' =>    987.767,
  'C6' =>   1046.502,
  'C#6' =>  1108.731,
  'Db6' =>  1108.731,
  'D6' =>   1174.659,
  'D#6' =>  1244.508,
  'Eb6' =>  1244.508,
  'E6' =>   1318.510,
  'F6' =>   1396.913,
  'F#6' =>  1479.978,
  'Gb6' =>  1479.978,
  'G6' =>   1567.982,
  'G#6' =>  1661.219,
  'Ab6' =>  1661.219,
  'A6' =>   1760.000,
  'A#6' =>  1864.655,
  'Bb6' =>  1864.655,
  'B6' =>   1975.533,
  'C7' =>   2093.005,
  'C#7' =>  2217.461,
  'Db7' =>  2217.461,
  'D7' =>   2349.318,
  'D#7' =>  2489.016,
  'Eb7' =>  2489.016,
  'E7' =>   2637.021,
  'F7' =>   2793.826,
  'F#7' =>  2959.956,
  'Gb7' =>  2959.956,
  'G7' =>   3135.964,
  'G#7' =>  3322.438,
  'Ab7' =>  3322.438,
  'A7' =>   3520.000,
  'A#7' =>  3729.310,
  'Bb7' =>  3729.310,
  'B7' =>   3951.066,
  'C8' =>   4186.009,
  'C#8' =>  4434.922,
  'Db8' =>  4434.922,
  'D8' =>   4698.636,
  'D#8' =>  4978.032,
  'Eb8' =>  4978.032,
  'E8' =>   5274.042,
  'F8' =>   5587.652,
  'F#8' =>  5919.910,
  'Gb8' =>  5919.910,
  'G8' =>   6271.928,
  'G#8' =>  6644.876,
  'Ab8' =>  6644.876,
  'A8' =>   7040.000,
  'A#8' =>  7458.620,
  'Bb8' =>  7458.620,
  'B8' =>   7902.132,
  'C9' =>   8372.018,
  'C#9' =>  8869.844,
  'Db9' =>  8869.844,
  'D9' =>   9397.272,
  'D#9' =>  9956.064,
  'Eb9' =>  9956.064,
  'E9' =>  10548.084,
  'F9' =>  11175.304,
  'F#9' => 11839.820,
  'Gb9' => 11839.820,
  'G9' =>  12543.856,
  'G#9' => 13289.752,
  'Ab9' => 13289.752,
  'A9' =>  14080.000,
  'A#9' => 14917.240,
  'Bb9' => 14917.240,
  'B9' =>  15804.264
  ]

  # error messages
  ERROR_MSG = Hash[
    :invalid_note             => 'Note name argument is invalid.',
    :invalid_scale            => "Scale ID is invalid. Valid IDs are: #{SCALES.keys}",
    :invalid_scale_root_note  => 'Scale cannot start with that note/frequency.',
    :invalid_waveform => "Waveform type is invalid. Valid waveform types are: #{WAVE_TYPES}",
    :scale_needs_note => 'You need to enter a valid note (-n) if you want to play a scale.'
  ]
end
